package fr.insalyon.sims.broadcast.network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;

/**
 * This class is a stream transmitter for multicast, i.e. UDP protocol.
 * 
 * @author GONZALEZ Silvia, GOTTERO Jeremie, SATTAYAKAWEE Nutchanat
 */
public class MCastStreamTransmitter extends BaseStreamTransmitter {
	// ------------------------------------------------------- CONSTANTS -- //
	// ------------------------------------------------------ ATTRIBUTES -- //
	
	/**
	 * Multicast group to be joined by its clients
	 */
    private InetAddress group;
	
    /**
     * Multicast port
     */
	private int port;
	
	/**
	 * socket of multicast server
	 */
	private MulticastSocket socket;
	
	/**
	 * number of the frame to be sent
	 */
	private long frameNumber;
	
	// ---------------------------------------------------- CONSTRUCTORS -- //
	
	/**
	 * Constructor
	 * 
	 * @param address group identifier of multicast server
	 * @param multicastPort multicast port to be bound by client
	 */
	public MCastStreamTransmitter(InetAddress group, int multicastPort) {
		this.group = group;
		port = multicastPort;
		frameNumber = 0;
	}
	
	// --------------------------------------------------------- METHODS -- //
	

	/**
	 * Opens MCastStreamTransmitter connection
	 * 
	 * @throws SocketException if the socket could not be opened
	 */
	public void connect() throws IOException {
		socket = new MulticastSocket(port);
		socket.joinGroup(group);
		socket.setSoTimeout(10000);
	}


	/**
	 * Closes MCastStreamTransmitter connection
	 */
	public void disconnect() {
		socket.close();
	}
	
	// ------------------------------------------------- PRIVATE METHODS -- //

	protected void init() {
		// No initialization job to do here
	}
	
	/**
	 * Send data to the clients
	 */
	protected void writeStream(byte[] data, int offset, int length) throws IOException {
		// Send packet
		DatagramPacket packet = new DatagramPacket(data, offset, length, group, port);
		socket.send(packet);
		
//		int packets = (int) Math.ceil(length / (double) DEFAULT_BUFFER_SIZE);
//		
//		for (int i = 0; i < packets; i++) {
//			// Create new array in order to put the number of the frame at the
//			// beginning of data array
//			int newLength = i == packets - 1 ? // is last packet ?
//				length - DEFAULT_BUFFER_SIZE * i + 8 : // last packet - size depends on length
//				DEFAULT_BUFFER_SIZE + 8; 			   // 2ko packet
//			byte[] newData = new byte[newLength];
//			System.arraycopy(data, i * DEFAULT_BUFFER_SIZE, newData, 8, newLength - 8);
//			
//			// Set frame number
//			for (int j = 0; j < 8; j++)
//				newData[7 - j] = (byte) ((frameNumber >> (j * 8)) & 0xff);
//			
//			// Send packet
//			DatagramPacket packet = new DatagramPacket(newData, newLength, group, port);
//			socket.send(packet);
//			
//			frameNumber++;
//		}
	}
	
	protected void cleanUp() {
		// No clean up job to do here
	}
	
	// --------------------------------------------------- INNER CLASSES -- //
	
}